package com.sunriz.javafx.views;

import com.sunriz.javafx.MainApplication;
import com.sunriz.javafx.server.Constant.ScadaConstant;
import com.sunriz.javafx.server.model.DTO.ScadaConfigDTO;
import com.sunriz.javafx.server.utils.Scada.FileManager;
import com.sunriz.javafx.server.utils.Scada.ScadaConfigUtil;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;


import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * ClassName: scadaController
 * Package: com.sunriz.javafx.views
 * Description:
 *
 * @Author BuTang
 * @Create 2024/12/19 14:40
 * @Version 1.0
 */
@Slf4j
public class ScadaController {

    private static List<ScadaConfigDTO> scadaConfig = new ArrayList<>();

    static {
        List<String> fileList = ScadaConfigUtil.getFileList();
        if (fileList.size() != 0) {
            ScadaConstant.fileName = fileList.get(0);
        }
    }

    public static void show(Stage stage) {
// 创建导航栏
        HBox navBar = new HBox();
        navBar.setStyle("-fx-background-color: #34495e; " + // 深灰色背景
                "-fx-padding: 10px; " +
                "-fx-alignment: center-left; " +
                "-fx-spacing: 15;"); // 设置间距

// 设置按钮样式
        String buttonStyle = "-fx-background-color: #ecf0f1; " + // 浅灰色背景
                "-fx-background-insets: 0, 1, 2; " +
                "-fx-background-radius: 2px; " +
                "-fx-text-fill: #2c3e50; " + // 深灰色文字
                "-fx-border-color: #7f8c8d; " + // 边框颜色
                "-fx-border-insets: 1; " +
                "-fx-border-radius: 2px; " +
                "-fx-font-weight: bold; " +
                "";

// 设置按钮动作
        Button btnHome = new Button("首页");
        btnHome.setOnAction(e -> MainApplication.show(stage));
        btnHome.setStyle(buttonStyle);

        Button btnSettings = new Button("设置");
        btnSettings.setStyle(buttonStyle);

        Button btnHelp = new Button("帮助");
        btnHelp.setStyle(buttonStyle);

// 将按钮添加到导航栏
        navBar.getChildren().addAll(btnHome, btnSettings, btnHelp);
        HBox.setMargin(btnHome, new Insets(0, 0, 0, 0));
        HBox.setMargin(btnSettings, new Insets(0, 0, 0, 0));
        HBox.setMargin(btnHelp, new Insets(0, 10, 0, 0));

        // 创建左侧的配置区域（占 20% 宽度）
        VBox leftPane = new VBox();
        leftPane.setStyle("-fx-background-color: lightgray; ");
        leftPane.setAlignment(Pos.TOP_LEFT);

        // 创建树形图
        TreeView<String> treeView = createTree();

        //=======================下拉框行====================================
        // 创建ComboBox
        ComboBox<String> comboBox = new ComboBox<>();
        List<String> fileList = ScadaConfigUtil.getFileList();
        ObservableList<String> options = FXCollections.observableArrayList();
        fileList.forEach(s -> options.add(s));
        comboBox.setItems(options);

        comboBox.setValue(options.get(0));

        // 创建添加和删除按钮
        Button addButton = new Button("+");
        Button deleteButton = new Button("-");
        // 设置添加按钮的事件处理器
        addButton.setOnAction(event -> addButtonSetting(comboBox));
        deleteButton.setOnAction(event -> deleteButtonSetting(comboBox));

        // 为按钮设置Tooltip
        Tooltip addButtonTooltip = new Tooltip("添加配置文件");
        Tooltip deleteButtonTooltip = new Tooltip("删除配置文件");
        // 设置显示延迟时间为0（即立即显示）
        addButtonTooltip.setShowDelay(Duration.ZERO);
        deleteButtonTooltip.setShowDelay(Duration.ZERO);
        addButton.setTooltip(addButtonTooltip);
        deleteButton.setTooltip(deleteButtonTooltip);

        // 创建HBox来包裹下拉框和按钮
        HBox hBox = new HBox(); // 设置控件之间的间距
        hBox.setAlignment(Pos.CENTER_LEFT); // 控件的对齐方式
        hBox.setMaxWidth(Double.MAX_VALUE); // 确保HBox的宽度能占满父容器

        // 创建StackPane来包装ComboBox，确保其可以扩展
        StackPane comboBoxWrapper = new StackPane();
        comboBoxWrapper.getChildren().add(comboBox);
        comboBoxWrapper.setMaxWidth(Double.MAX_VALUE);
        hBox.getChildren().addAll(comboBoxWrapper, addButton, deleteButton);
        HBox.setHgrow(comboBoxWrapper, Priority.ALWAYS);
        leftPane.getChildren().add(hBox);

        //=========================添加删除节点==================================

        // 设置垂直伸展
        VBox.setVgrow(leftPane, Priority.ALWAYS);


        // 创建“添加设备”按钮
        Button btnAddNode = new Button("添加节点");
        btnAddNode.setOnAction(event -> {
            // 获取当前选中的节点
            TreeItem<String> selectedItem = treeView.getSelectionModel().getSelectedItem();

            if (selectedItem != null) {
                // 创建新的节点并将其添加到当前选中节点下
                String newNodeName = "1";  // 你可以在这里定义新的节点名
                TreeItem<String> newItem = new TreeItem<>(newNodeName);

                // 将新节点添加为选中节点的子节点
                selectedItem.getChildren().add(newItem);

                // 选中新添加的节点
                treeView.getSelectionModel().select(newItem);

                // 更新树的数据
                ScadaConfigUtil.updateScadaConfig(treeView);
            }
        });

        // 创建“删除设备”按钮
        Button btnDeleteNode = new Button("删除节点");
        btnDeleteNode.setOnAction(event -> {
            // 获取当前选中的节点
            TreeItem<String> selectedItem = treeView.getSelectionModel().getSelectedItem();

            if (selectedItem != null && selectedItem.getParent() != null) {
                // 从父节点中删除选中的节点
                selectedItem.getParent().getChildren().remove(selectedItem);

                // 更新树的数据
                ScadaConfigUtil.updateScadaConfig(treeView);
            }
        });

        // 创建添加设备按钮的StackPane包装器
        HBox buttonBox = new HBox();
        StackPane addNodeWrapper = new StackPane();
        addNodeWrapper.getChildren().add(btnAddNode);
        StackPane deleteNodeWrapper = new StackPane();
        deleteNodeWrapper.getChildren().add(btnDeleteNode);
        HBox.setHgrow(addNodeWrapper, Priority.ALWAYS);
        HBox.setHgrow(deleteNodeWrapper, Priority.ALWAYS);
        // 将按钮包装器添加到按钮容器
        buttonBox.getChildren().addAll(addNodeWrapper, deleteNodeWrapper);
        // 设置按钮的样式，确保它们可以扩展
        btnAddNode.setMaxWidth(Double.MAX_VALUE);
        btnDeleteNode.setMaxWidth(Double.MAX_VALUE);
        // 将按钮容器添加到左侧面板
        leftPane.getChildren().add(buttonBox);

        // 确保 leftPane 能够垂直扩展并占满剩余空间
        leftPane.setMinWidth(100);
        leftPane.setMaxWidth(200);
        VBox.setVgrow(leftPane, Priority.ALWAYS);


        //=========================添加树状图==================================
        // 将树状图添加到容器中
        leftPane.getChildren().add(treeView);
        VBox.setVgrow(treeView, Priority.ALWAYS);

        // 创建右侧的内容区域（占 80% 宽度）
        VBox rightPane = new VBox();
        rightPane.setStyle("-fx-padding: 20px;");

        //=========================数据展示==================================
        TableView tableView = new TableView();
        updateTableView(tableView);

        //=========================选择框点击逻辑==================================
        comboBox.setOnAction(event -> {
            String selected = comboBox.getValue();
            ScadaConstant.fileName = selected;
            System.out.println("选中的选项是: " + selected);
            updateTree(treeView.getRoot());
            updateTableView(tableView);
        });

        //=========================界面设计==================================
        // 将表格添加到右侧面板
        rightPane.getChildren().add(tableView);
        VBox.setVgrow(rightPane, Priority.ALWAYS);  // 设置垂直伸展

        // 创建一个 SplitPane，允许用户调整左侧和右侧区域的大小
        SplitPane splitPane = new SplitPane();
        splitPane.setDividerPositions(0.2); // 设置初始比例，左侧占 20%

        // 将左侧和右侧区域加入到 SplitPane 中
        splitPane.getItems().addAll(leftPane, rightPane);

        // 创建一个垂直的布局，包含导航栏和主内容区域
        VBox mainLayout = new VBox();
        VBox.setVgrow(splitPane, Priority.ALWAYS);  // 确保 SplitPane 会垂直伸展
        mainLayout.getChildren().addAll(navBar, splitPane);

        // 创建场景并显示
        Scene scene = new Scene(mainLayout, 1100, 750);
        stage.setTitle("Scada");
        stage.setScene(scene);
        stage.show();
    }


    /**
     * 创建可编辑的树形图
     *
     * @return
     */
    private static TreeView<String> createTree() {

        // 创建根节点
        TreeItem<String> rootItem = new TreeItem<>("配置信息");
        rootItem.setExpanded(true);

        // 加载scadaConfig,并放到树形图内
        updateTree(rootItem);

        // 创建树形图并启用编辑
        TreeView<String> treeView = new TreeView<>(rootItem);
        treeView.setEditable(true);

        // 自定义TreeCell，允许编辑树节点的值
        treeView.setCellFactory(param -> new TreeCell<String>() {
            private TextField textField;

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (empty || item == null) {
                    setText(null);
                    setGraphic(null);
                } else {
                    TreeItem<String> currentItem = getTreeItem();

                    if (currentItem != null) {
                        // 第一层子节点，前缀是"SlaveId"
                        if (currentItem.getParent() != null && currentItem.getParent().getParent() == null) {
                            setText("SlaveId: " + item);
                        }
                        // 第二层子节点，前缀是"Address"
                        else if (currentItem.getParent() != null && currentItem.getParent().getParent() != null) {
                            setText("Address: " + item);
                        }
                        // 根节点不加任何前缀
                        else {
                            setText(item);
                        }
                    }
                }
            }


            @Override
            public void startEdit() {
                super.startEdit();
                if (textField == null) {
                    textField = new TextField(getItem());
                    textField.setPrefWidth(70);  // 设置宽度为 100px，适合四五个数字
                }
                setGraphic(textField);
                textField.selectAll();

                // 确保 TextField 响应 Enter 键
                textField.setOnAction(event -> {
                    commitEdit(textField.getText());  // 提交编辑
                });

                // 监听失去焦点事件，点击其它地方时保存编辑内容
                textField.focusedProperty().addListener((observable, oldValue, newValue) -> {
                    if (!newValue) {
                        // 当焦点失去时（点击其他地方），提交当前编辑
                        commitEdit(textField.getText());
                    }
                });
            }


            @Override
            public void commitEdit(String newValue) {
                super.commitEdit(newValue);
                setGraphic(null);
                // 更新 TreeItem 的值
                if (getTreeItem() != null) {
                    getTreeItem().setValue(newValue); // 更新节点的值
                }
                ScadaConfigUtil.updateScadaConfig(treeView);
            }

        });

        return treeView;
    }


    /**
     * 更新树状图
     *
     * @param rootItem
     * @return
     */
    private static TreeItem<String> updateTree(TreeItem<String> rootItem) {

        // 清空树状图中的所有数据
        rootItem.getChildren().clear();
        // 加载scadaConfig,并放到树形图内
        scadaConfig = ScadaConfigUtil.readScadaConfig();
        scadaConfig.forEach(scadaConfigDTO -> {
            // 示例数据：多个 slaveID，每个 slaveID 包含多个 address
            TreeItem<String> slave = new TreeItem<>(scadaConfigDTO.slaveId);
            scadaConfigDTO.infos.forEach(info -> {
                slave.getChildren().add(new TreeItem<>(String.valueOf(info.getAddress())));
            });
            rootItem.getChildren().addAll(slave);
        });
        return rootItem;
    }


    private static void updateTableView(TableView tableView) {
        // 先清除表格中的所有列
        tableView.getColumns().clear();

        // 创建表格列，将列添加到表格
        scadaConfig.forEach(scadaConfigDTO -> {
            TableColumn tableViewColumn = new TableColumn(scadaConfigDTO.slaveId);
            tableView.getColumns().add(tableViewColumn);
        });
    }
    private static void addButtonSetting(ComboBox<String> comboBox) {
        TextInputDialog dialog = new TextInputDialog("newFile.json");
        dialog.setTitle("添加文件");
        dialog.setHeaderText(null);
        dialog.setContentText("文件名:");


        dialog.showAndWait().ifPresent(name -> {
            if (name != null && !name.isEmpty()) {
                // 将新文件名添加到ComboBox中
                comboBox.getItems().add(name);
                comboBox.setValue(name);
                // 这里可以添加代码将文件名保存到文件或更新文件列表
                String s = FileManager.addFile(name);
                log.info(s);
            }
        });
    }

    private static void deleteButtonSetting(ComboBox<String> comboBox) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setTitle("删除文件");
        alert.setHeaderText(null);
        alert.setContentText("确定要删除该文件 "+ScadaConstant.fileName+" 吗?");

        ButtonType buttonTypeYes = new ButtonType("是");
        ButtonType buttonTypeNo = new ButtonType("否");
        alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeNo);
        // 显示确认对话框
        Optional<ButtonType> result = alert.showAndWait();
        if (result.get() == buttonTypeYes) {
            String s = FileManager.deleteFile(ScadaConstant.fileName);
            log.info(s);
        }
    }
}